import os
from typing import Optional, Union

from app.config.settings import settings


def extract_filename_without_extension(source) -> Optional[str]:
    """
    如果输入source类型为str或文件对象，提取文件名，不包括后缀，并返回文件名，否则返回None

    Args:
        source: 输入源，可以是字符串（文件路径）、文件对象或其他类型

    Returns:
        Optional[str]: 文件名（不包括扩展名）或None
    """
    if isinstance(source, str):
        # 处理字符串类型的文件路径
        filename_with_extension = os.path.basename(source)
        filename_without_extension = os.path.splitext(filename_with_extension)[0]
        return filename_without_extension
    elif hasattr(source, 'name') and isinstance(source.name, str):
        # 处理具有name属性的文件对象（如open()返回的文件对象）
        filename_with_extension = os.path.basename(source.name)
        filename_without_extension = os.path.splitext(filename_with_extension)[0]
        return filename_without_extension
    else:
        # 其他类型返回None
        return None


def build_output_path_with_page_info(source, page_index: Union[int, str] | None = None, base_output_dir: str = "./output") -> str:
    """
    构建包含页面信息的输出路径
    
    Args:
        source: 输入源，可以是字符串（文件路径）或文件对象
        page_index: 页面索引，可以是整数或字符串
        base_output_dir: 基础输出目录路径，默认为"./output"
        
    Returns:
        str: 构建好的输出路径
    """
    # 获取文件名（不包含扩展名）
    file_name = extract_filename_without_extension(source)
    if file_name is None:
        file_name = "unknown"

    # 如果提供了 page_index，则添加到路径中
    if page_index is not None:
        # 构建输出路径: base_output_dir/文件名/页面索引
        output_path = os.path.join(base_output_dir, file_name, str(page_index))
    else:
        # 构建输出路径: base_output_dir/文件名
        output_path = os.path.join(base_output_dir, file_name)

    return output_path


def clear_directory(target_dir, r=False):
    """
    删除目标目录下的所有文件。

    :param target_dir: str, 要清理的目录路径。
    :param r: bool, 是否递归删除子目录中的文件，默认为False。
    """
    if not os.path.isdir(target_dir):
        print(f"警告：'{target_dir}' 不是有效的目录路径。")
        return

    for root, dirs, files in os.walk(target_dir):
        for file in files:
            file_path = os.path.join(root, file)
            try:
                os.unlink(file_path)  # 删除文件
                # print(f"已删除文件：{file_path}")
            except Exception as e:
                print(f"删除文件时出错：{file_path} - {e}")

        # 如果不递归删除，则在处理完第一个目录层级后跳出循环
        if not r:
            break

    # 如果递归删除并且需要清理空的子目录
    if r:
        for root, dirs, files in os.walk(target_dir, topdown=False):
            for dir in dirs:
                dir_path = os.path.join(root, dir)
                if not os.listdir(dir_path):  # 如果目录为空
                    try:
                        os.rmdir(dir_path)  # 删除空目录
                        print(f"已删除空目录：{dir_path}")
                    except Exception as e:
                        print(f"删除目录时出错：{dir_path} - {e}")


def clear_logs():
    try:
        # 获取基础日志文件路径
        app_file_path = settings.get('logging.app_file_path')
        system_file_path = settings.get('logging.system_file_path')
        error_file_path = settings.get('logging.error_file_path')
        all_file_path = settings.get('logging.all_file_path')

        # 收集所有需要清空的日志文件路径
        log_files = [
            app_file_path,
            system_file_path,
            error_file_path,
            all_file_path,
            "../logs/uvicorn.log",
            "../logs/access.log",
        ]

        # 从third_party配置中获取第三方库日志文件路径
        third_party_cfg = settings.get('logging.third_party', {})
        for logger_name, cfg in third_party_cfg.items():
            target = cfg.get('target')
            if target == "separate" and 'file' in cfg:
                log_files.append(cfg['file'])
            elif isinstance(target, dict):
                for level_key, dest in target.items():
                    if isinstance(dest, str):
                        # 简单的文件路径
                        log_files.append(dest)
                    elif isinstance(dest, dict) and 'file' in dest:
                        # 字典形式的配置，检查init_file选项
                        if dest.get('init_file', True):
                            log_files.append(dest['file'])

        # 确保所有需要初始化的日志文件的目录存在
        for log_file in log_files:
            os.makedirs(os.path.dirname(log_file), exist_ok=True)

        # 清空所有需要初始化的日志文件内容
        for log_file in log_files:
            with open(log_file, 'w'):
                pass
    except Exception as e:
        print(f"清空日志文件失败: {e}")
